home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 19 / develop 19 code / SimpliFace_V2 / Sources / ListOfLongs.cp < prev    next >
Encoding:
Text File  |  1994-05-01  |  8.0 KB  |  482 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        ListOfLongs.cp
  4.  
  5.     Contains:    TListOfLongs implementation.
  6.  
  7.  
  8.     Developed by:
  9.  
  10.     Paul G Smith (commstalk hq & Full Moon Software, Inc)
  11.  
  12.     you can leave messages at (UK): 0727 844232; (US): 408 253 7199
  13.     BUT I prefer to be contacted by e-mail
  14.     AppleLink:     COMMSTALK.HQ
  15.     Internet:     COMMSTALK.HQ@applelink.apple.com
  16.  
  17.     "SimpliFace2" Sample code to accompany develop article
  18.     on techniques for controlling script inheritance.
  19.     
  20.     
  21.  
  22.  
  23.  
  24.     Ordered and un-ordered lists of long integers
  25.  
  26. */
  27.  
  28. #include "ListOfLongs.h"
  29.  
  30. #ifndef __LIMITS__
  31. #include <Limits.h>
  32. #endif
  33.  
  34. #ifndef __ERRORS__
  35. #include <Errors.h>
  36. #endif
  37.  
  38. #ifndef __RESOURCES__
  39. #include <Resources.h>
  40. #endif
  41.  
  42. #ifndef __PACKAGES__
  43. #include <Packages.h>
  44. #endif
  45.  
  46.  
  47.  
  48.  
  49. const short kLListChunkUnit = 16;
  50. const short kLListChunkSize = kLListChunkUnit*sizeof(long);    // allocation chunk size
  51.  
  52. /*******************************************************************************
  53. ** TListOfLongs: Constructor/Destructor
  54. ********************************************************************************/
  55.  
  56. TListOfLongs::TListOfLongs()
  57. {
  58.     fNumItems = 0;
  59.     fDataHandle = NewHandle(kLListChunkSize);
  60. }
  61.  
  62.  
  63. TListOfLongs::TListOfLongs(const TListOfLongs& oldObj)
  64. {
  65.     Handle h = oldObj.fDataHandle;
  66.     HandToHand(&h);
  67.     if (h)
  68.         fDataHandle = h;
  69.     fNumItems = oldObj.fNumItems;
  70. }
  71.  
  72.  
  73. TListOfLongs::~TListOfLongs(void)
  74. {
  75.     if (fDataHandle)
  76.         DisposHandle(fDataHandle);
  77. }
  78.  
  79.  
  80. TListOfLongs& TListOfLongs::operator=(const TListOfLongs& oldObj)
  81. {
  82.     if (this != &oldObj)
  83.     {
  84.         Handle h = oldObj.fDataHandle;
  85.         HandToHand(&h);
  86.         if (h)
  87.         {
  88.             if (fDataHandle)
  89.                 DisposHandle(fDataHandle);
  90.             fDataHandle = h;
  91.         }
  92.         fNumItems = oldObj.fNumItems;
  93.     }
  94.     return *this;
  95. }
  96.  
  97.  
  98. // the business
  99.  
  100. Handle TListOfLongs::GetData(void)
  101. {
  102.     Handle     h = NULL;
  103.     long     numElems = fNumItems;
  104.     OSErr    err = 0;
  105.     
  106.     if ((numElems > 0) && fDataHandle)
  107.     {
  108.         HLock(fDataHandle);
  109.         err = PtrToHand(*fDataHandle, &h, numElems*sizeof(long));
  110.         HUnlock(fDataHandle);
  111.     }
  112.     else
  113.         h = NewHandle(0);
  114.     
  115.     return h;
  116. }
  117.  
  118.  
  119. void TListOfLongs::SetData(Handle h)
  120. {
  121.     fNumItems = 0;
  122.     
  123.     if (h)
  124.     {
  125.         long     hs = GetHandleSize(h);
  126.         long    numItems = hs / sizeof(long);
  127.         if (numItems < 0)
  128.             numItems = 0;
  129.         if (numItems)
  130.         {
  131.             Handle nh = h;
  132.             OSErr err = HandToHand(&nh);
  133.             if (err == noErr)
  134.             {
  135.                 fNumItems = numItems;
  136.                 DisposHandle(fDataHandle);
  137.                 fDataHandle = nh;
  138.             }
  139.         }
  140.     }
  141. }
  142.  
  143.  
  144.  
  145. OSErr TListOfLongs::ExpandDataHandle(long numLongs)
  146. {
  147.     OSErr err = 0;
  148.     
  149.     if (fDataHandle)
  150.     {
  151.         long     numElems = fNumItems;
  152.         Handle    h = fDataHandle;
  153.         long    oldSize = GetHandleSize(h);
  154.         
  155.         if (((numElems+numLongs) * sizeof(long)) > oldSize)
  156.         {
  157.             long    addSize = (numLongs / kLListChunkUnit) + 1;
  158.  
  159.             SetHandleSize(h, oldSize + addSize * kLListChunkSize);
  160.             err = MemError();
  161.         }
  162.     }
  163.     else
  164.         err = nilHandleErr;
  165.     
  166.     return err;
  167. }
  168.  
  169.  
  170.  
  171. OSErr TListOfLongs::ShrinkDataHandle(long numLongs)
  172. {
  173.     return noErr;        // do nothing, for time being
  174. }
  175.  
  176.  
  177.  
  178. OSErr TListOfLongs::InsertElement(long val)
  179. {
  180.     OSErr err = noErr;
  181.     
  182.     if (!FindElement(val))    // if it's already there, do nothing
  183.     {
  184.         long     lastItem = fNumItems;    
  185.         long**     dh = (long**) fDataHandle;
  186.         
  187.         err = ExpandDataHandle(1);    // grows dh, if more room is needed
  188.             
  189.         HLock(fDataHandle);        // locks dh
  190.         
  191.         while (lastItem > 0)
  192.         {
  193.             long     lastVal = (*dh)[lastItem-1];    // because array is indexed from 0
  194.             if (lastVal > val)
  195.             {
  196.                 (*dh)[lastItem] = lastVal;
  197.                 lastItem--;
  198.             }
  199.             else
  200.                 break;    // insert here!
  201.         }
  202.         (*dh)[lastItem] = val;
  203.         fNumItems = fNumItems + 1;
  204.         
  205.         HUnlock(fDataHandle);
  206.     }
  207.     
  208.     return err;
  209. }
  210.  
  211.  
  212. void TListOfLongs::DeleteElement(long val)
  213. {
  214.     long    foundIndex = FindElement(val);
  215.     
  216.     if (foundIndex)
  217.     {
  218.         long     numElems = fNumItems;
  219.         
  220.         if ((numElems > 0) && fDataHandle)
  221.         {
  222.             long**     dh = (long**) fDataHandle;
  223.             long    currentIndex = foundIndex-1;
  224.             
  225.             HLock(fDataHandle);        // locks dh
  226.         
  227.             while (currentIndex < numElems-1)
  228.             {
  229.                 (*dh)[currentIndex] = (*dh)[currentIndex+1];
  230.                 currentIndex++;
  231.             }
  232.             fNumItems = fNumItems - 1;
  233.         
  234.             HUnlock(fDataHandle);
  235.             
  236.             ShrinkDataHandle(1);
  237.         }
  238.     }
  239. }
  240.  
  241.  
  242.  
  243.  
  244. long TListOfLongs::GetElement(long index)
  245. {
  246.     long     numElems = fNumItems;
  247.     
  248.     if ((numElems > 0) && fDataHandle)
  249.     {
  250.         long**     dh = (long**) fDataHandle;
  251.         long    val = 0;
  252.         
  253.         HLock(fDataHandle);    // locks dh
  254.         val = (*dh)[index-1];
  255.         HUnlock(fDataHandle);
  256.         
  257.         return val;
  258.     }
  259.     else
  260.         return 0;
  261. }
  262.  
  263.  
  264. long TListOfLongs::FindElement(long val)
  265. {
  266.     long     numElems = fNumItems;
  267.     
  268.     if ((numElems > 0) && fDataHandle)
  269.     {
  270.         long**     dh = (long**) fDataHandle;
  271.         long     currentIndex = 0;
  272.         long     currentVal = 0;
  273.         long     lowBound = 1;
  274.         long     highBound = numElems;
  275.         Boolean    found = false;
  276.         
  277.         HLock(fDataHandle);    // locks dh
  278.         
  279.         do
  280.         {
  281.             currentIndex = (lowBound + highBound) >> 1;      // == divide by 2
  282.             currentVal = (*dh)[currentIndex-1];
  283.             if (val < currentVal)
  284.                 highBound = currentIndex-1;
  285.             else
  286.                 lowBound = currentIndex+1;
  287.             found = (val == currentVal);
  288.         } while (!(found || (lowBound > highBound)));
  289.         
  290.         if (!found)
  291.             currentIndex = 0;
  292.             
  293.         HUnlock(fDataHandle);
  294.         
  295.         return currentIndex;
  296.     }
  297.     else
  298.         return 0;
  299. }
  300.  
  301.  
  302.  
  303. /*******************************************************************************
  304. ** TOrderedListOfLongs: Constructor/Destructor
  305. ********************************************************************************/
  306.  
  307. TOrderedListOfLongs::TOrderedListOfLongs()
  308. {
  309. }
  310.  
  311.  
  312. TOrderedListOfLongs::TOrderedListOfLongs(const TOrderedListOfLongs& oldObj)
  313. {
  314.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  315. }
  316.  
  317.  
  318. TOrderedListOfLongs::~TOrderedListOfLongs(void)
  319. {
  320. }
  321.  
  322.  
  323. TOrderedListOfLongs& TOrderedListOfLongs::operator=(const TOrderedListOfLongs& oldObj)
  324. {
  325.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  326.     return *this;
  327. }
  328.  
  329.  
  330. // the business
  331.  
  332.  
  333. OSErr TOrderedListOfLongs::InsertElement(long val)
  334. {
  335.     return -1;
  336. }
  337.  
  338.  
  339. OSErr TOrderedListOfLongs::InsertElementAt(long val, long index)
  340. {
  341.     OSErr err = noErr;
  342.     
  343.     if (!FindElement(val))    // if it's already there, do nothing
  344.     {
  345.         long     lastItem = fNumItems;    
  346.         long**     dh = (long**) fDataHandle;
  347.         
  348.         err = ExpandDataHandle(1);    // grows dh, if more room is needed
  349.             
  350.         HLock(fDataHandle);        // locks dh
  351.         
  352.         if (index <= 1)
  353.             index = 1;
  354.         while (lastItem >= index)
  355.         {
  356.             (*dh)[lastItem] = (*dh)[lastItem-1]; // because array is indexed from 0
  357.             lastItem--;
  358.         }
  359.         (*dh)[lastItem] = val;
  360.         fNumItems = fNumItems + 1;
  361.         
  362.         HUnlock(fDataHandle);
  363.     }
  364.     
  365.     return err;
  366. }
  367.  
  368.  
  369. long TOrderedListOfLongs::FindElement(long val)
  370. {
  371.     long     numElems = fNumItems;
  372.     
  373.     if ((numElems > 0) && fDataHandle)
  374.     {
  375.         long**     dh = (long**) fDataHandle;
  376.         long     currentIndex = numElems;
  377.         long     currentVal;
  378.         Boolean    found = false;
  379.         
  380.         HLock(fDataHandle);    // locks dh
  381.         
  382.         do
  383.         {
  384.             currentVal = (*dh)[currentIndex-1];
  385.             found = (val == currentVal);
  386.             if (!found)
  387.                 currentIndex--;
  388.         } while (!found && currentIndex > 0);
  389.         
  390.         if (!found)
  391.             currentIndex = 0;
  392.             
  393.         HUnlock(fDataHandle);
  394.         
  395.         return currentIndex;
  396.     }
  397.     else
  398.         return 0;
  399. }
  400.  
  401.  
  402.  
  403. /*******************************************************************************
  404. ** TStackOfLongs: Constructor/Destructor
  405. ********************************************************************************/
  406.  
  407. TStackOfLongs::TStackOfLongs()
  408. {
  409. }
  410.  
  411.  
  412. TStackOfLongs::TStackOfLongs(const TStackOfLongs& oldObj)
  413. {
  414.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  415. }
  416.  
  417.  
  418. TStackOfLongs::~TStackOfLongs(void)
  419. {
  420. }
  421.  
  422.  
  423. TStackOfLongs& TStackOfLongs::operator=(const TStackOfLongs& oldObj)
  424. {
  425.     (TListOfLongs&)(*this) = (TListOfLongs&)oldObj;
  426.     return *this;
  427. }
  428.  
  429.  
  430. // the business
  431.  
  432.  
  433. OSErr TStackOfLongs::InsertElement(long val)
  434. {
  435.     return -1;
  436. }
  437.  
  438.  
  439. long TStackOfLongs::FindElement(long val)
  440. {
  441.     return -1;
  442. }
  443.  
  444.  
  445.  
  446. OSErr TStackOfLongs::PushElement(long val)
  447. {
  448.     OSErr     err = noErr;
  449.     long     lastItem = fNumItems;    
  450.     long**     dh = (long**) fDataHandle;
  451.     
  452.     err = ExpandDataHandle(1);    // grows dh, if more room is needed
  453.         
  454.     HLock(fDataHandle);        // locks dh
  455.     (*dh)[lastItem] = val;
  456.     fNumItems = fNumItems + 1;
  457.     HUnlock(fDataHandle);
  458.     
  459.     return err;
  460. }
  461.  
  462.  
  463. OSErr TStackOfLongs::PopElement(long *val)
  464. {
  465.     OSErr     err = noErr;
  466.     long    lastItem = fNumItems;    
  467.     long**     dh = (long**) fDataHandle;
  468.     
  469.     HLock(fDataHandle);        // locks dh
  470.     if (lastItem > 0)
  471.         *val = (*dh)[lastItem-1];
  472.     else
  473.         err = -1;
  474.     fNumItems = fNumItems - 1;
  475.     HUnlock(fDataHandle);
  476.     
  477.     if (err == noErr)
  478.         err = ShrinkDataHandle(1);
  479.         
  480.     return err;
  481. }
  482.